{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 字典"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 修改数据"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 2}"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = {}\n",
    "A['a'] = A.get('a', 0) + 1   # key=a不存在时返回0，即第二个入参\n",
    "A['a'] = A['a'] + 1    # key=a不存在时会出错\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 字典树用做统计功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 2, 'b': 3}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "dataSet = ['a', 'a', 'b', 'b', 'b']\n",
    "A = {}\n",
    "for data in dataSet:\n",
    "    A[data] = A.get(data, 0) + 1   # 因为第一次时key不存在，所以只能用这种形式读value\n",
    "A    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 2, 'b': 3}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = {}\n",
    "for data in dataSet:\n",
    "    if data not in A.keys():     # 或者对第一次做特殊处理\n",
    "        A[data] = 0\n",
    "    A[data] += 1\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 对字典树排序"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "[(4, 'd'), (2, 'c'), (3, 'b'), (1, 'a')]"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import operator\n",
    "A = {1:'a', 3:'b', 2:'c', 4:'d'}\n",
    "sorted(A.items(),   # iterable -- 可迭代对象，在python2中使用A.iteritems()，在python3中使用A.items()\n",
    "       key=operator.itemgetter(1),   # key -- 主要是用来进行比较的元素，指定可迭代对象中的一个元素来进行排序，这里指基于item的value进行排序\n",
    "       reverse=True)   # reverse -- 排序规则，reverse = True 降序 ， reverse = False 升序（默认）。\n",
    "# 排序结果是一个list"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{1: 'a', 3: 'b', 2: 'c', 4: 'd'}"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A   # A并没有改变"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 字典树用作store tree的功能"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 18,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'left0': {'left1': {'left2': 1, 'right2': 2},\n",
       "  'right1': {'left2': 3, 'right2': 4}},\n",
       " 'right0': {'left1': {'left2': 5, 'right2': 6},\n",
       "  'right1': {'left2': 7, 'right2': 8}}}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "def createTree(dataList, depth):   # 把一个list构造成二叉树\n",
    "    if len(dataList) == 1:return dataList[0]\n",
    "    midIndex = int(len(dataList)/2)\n",
    "    label1 = \"left\"+str(depth)\n",
    "    label2 = \"right\"+str(depth)\n",
    "    myTree = {label1:createTree(dataList[:midIndex], depth+1),   # 生成左子树\n",
    "              label2:createTree(dataList[midIndex:], depth+1)}   # 生成右子树\n",
    "    return myTree\n",
    "\n",
    "createTree([1,2,3,4,5,6,7,8], 0)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 取字典第一个key"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "dict_keys(['a', 'b'])"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = {'a':1, 'b':2}\n",
    "# 列出字典中的所有key\n",
    "keys = A.keys()\n",
    "keys"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "'dict_keys' object is not subscriptable",
     "output_type": "error",
     "traceback": [
      "\u001b[1;31m---------------------------------------------------------------------------\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m                                 Traceback (most recent call last)",
      "\u001b[1;32m<ipython-input-8-35820640b14b>\u001b[0m in \u001b[0;36m<module>\u001b[1;34m\u001b[0m\n\u001b[0;32m      1\u001b[0m \u001b[1;31m# 不能直接取keys[0]，因为它不是一个list。（python2可以直接keys[0]）\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[1;32m----> 2\u001b[1;33m \u001b[0mkeys\u001b[0m\u001b[1;33m[\u001b[0m\u001b[1;36m0\u001b[0m\u001b[1;33m]\u001b[0m\u001b[1;33m\u001b[0m\u001b[1;33m\u001b[0m\u001b[0m\n\u001b[0m",
      "\u001b[1;31mTypeError\u001b[0m: 'dict_keys' object is not subscriptable"
     ]
    }
   ],
   "source": [
    "# 不能直接取keys[0]，因为它不是一个list。（python2可以直接keys[0]）\n",
    "keys[0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "'a'"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "# 应该先转成list，再取第0个元素\n",
    "list(keys)[0]"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 两个字典相加"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 1, 'b': 2}"
      ]
     },
     "execution_count": 2,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = {'a':1}\n",
    "B = {'b':2}\n",
    "A.update(B)\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# 删除关键字"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'a': 1}"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "A = {'a':1, 'b':2}\n",
    "A.pop('b')\n",
    "A"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python中通过Key访问字典，当Key不存在时，会引发‘KeyError’异常。为了避免这种情况的发生，可以使用collections类中的defaultdict()方法来为字典提供默认值。\n",
    "[collections](https://windmissing.github.io/programming_basics_for_ML/python/collections.html)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "file_extension": ".py",
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  },
  "mimetype": "text/x-python",
  "name": "python",
  "npconvert_exporter": "python",
  "pygments_lexer": "ipython3",
  "version": 3
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
